package com.maodou.core.network

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.transform

/**
 * 简化的收集方法，自动处理成功和失败情况
 * @param onSuccess 成功时的回调
 * @param onFailure 失败时的回调（可选）
 * @param onLoading 开始加载时的回调（可选）
 * @param onComplete 完成时的回调（可选，无论成功失败都会调用）
 */
suspend inline fun <T> Flow<NetworkResult<T>>.collectResult(
    crossinline onSuccess: (T) -> Unit,
    crossinline onFailure: (NetworkError) -> Unit = {},
    crossinline onLoading: (Boolean) -> Unit = {},
    crossinline onComplete: () -> Unit = {}
) {
    onLoading(true)
    this.onEach { result ->
        when (result) {
            is NetworkResult.Success -> onSuccess(result.data)
            is NetworkResult.Failure -> onFailure(result.error)
        }
        onComplete()
        onLoading(false)
    }.collect()
}

/**
 * 更简洁的成功处理，忽略失败情况
 */
suspend inline fun <T> Flow<NetworkResult<T>>.collectSuccess(
    crossinline onSuccess: (T) -> Unit
) {
    this.onlySuccess().collect { data ->
        onSuccess(data)
    }
}

/**
 * 转换为普通的 Flow<T>，只发出成功的数据，失败时抛出异常
 */
fun <T> Flow<NetworkResult<T>>.unwrap(): Flow<T> =
    transform { result ->
        when (result) {
            is NetworkResult.Success -> emit(result.data)
            is NetworkResult.Failure -> throw NetworkException(result.error)
        }
    }

/**
 * 网络异常包装类
 */
class NetworkException(val networkError: NetworkError) : Exception(networkError.cause?.message)

/**
 * 提供默认值的收集方法
 */
suspend inline fun <T> Flow<NetworkResult<T>>.collectWithDefault(
    defaultValue: T,
    crossinline onResult: (T) -> Unit
) {
    this.recover { defaultValue }
        .onlySuccess()
        .collect { data ->
            onResult(data)
        }
}

/**
 * 链式调用风格的处理方法
 */
class NetworkResultHandler<T>(private val flow: Flow<NetworkResult<T>>) {
    private var onSuccessAction: ((T) -> Unit)? = null
    private var onFailureAction: ((NetworkError) -> Unit)? = null
    private var onLoadingAction: ((Boolean) -> Unit)? = null
    private var onCompleteAction: (() -> Unit)? = null

    fun onSuccess(action: (T) -> Unit): NetworkResultHandler<T> {
        onSuccessAction = action
        return this
    }

    fun onFailure(action: (NetworkError) -> Unit): NetworkResultHandler<T> {
        onFailureAction = action
        return this
    }

    fun onLoading(action: (Boolean) -> Unit): NetworkResultHandler<T> {
        onLoadingAction = action
        return this
    }

    fun onComplete(action: () -> Unit): NetworkResultHandler<T> {
        onCompleteAction = action
        return this
    }

    suspend fun collect() {
        flow.collectResult(
            onSuccess = onSuccessAction ?: {},
            onFailure = onFailureAction ?: {},
            onLoading = onLoadingAction ?: {},
            onComplete = onCompleteAction ?: {}
        )
    }
}

/**
 * 创建链式调用处理器
 */
fun <T> Flow<NetworkResult<T>>.handle(): NetworkResultHandler<T> =
    NetworkResultHandler(this)

/**
 * 便捷的单行处理方法
 */
suspend inline fun <T> Flow<NetworkResult<T>>.handleResult(
    crossinline onLoading: (Boolean) -> Unit = {},
    crossinline onSuccess: (T) -> Unit,
    crossinline onError: (NetworkError) -> Unit = {}
) {
    this.collectResult(
        onSuccess = onSuccess,
        onFailure = onError,
        onLoading = onLoading
    )
}